package com.cloudkinto.service.home.impl;



import com.cloudkinto.common.common.DateUtils;
import com.cloudkinto.common.utils.MathUtils;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.dao.CostDao;
import com.cloudkinto.dao.OrderInputDao;
import com.cloudkinto.dao.ProductStockDao;
import com.cloudkinto.dto.home.*;
import com.cloudkinto.service.home.HomePageService;
import com.cloudkinto.service.home.vo.HomeCostRes;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)//事务回滚
public class HomePageServiceImpl implements HomePageService {
    private final OrderInputDao orderInputDao;
    private final ProductStockDao productStockDao;
    private final CostDao costDao;

    /**
     * todoData 最上方统计
     */
    @Override
    public List<HomeTodoData> getTodoData(String source, Long userId, Long companyId, Long whId, Long tenantId) {
        //带入库数量
        List<HomeTodoData> homeTodoData = orderInputDao.getHomeTodoData(source, userId, companyId, whId, tenantId);
        return homeTodoData;
    }


    /**
     * 单量分析 omp/wms
     * 按照提交时间统计完成的数量
     */
    @Override
    public List<HomeTodoData> getOrderFinishCount(Map<String, Object> map) {
        List<HomeTodoData> orderCount = orderInputDao.getOrderCount(map);
        return orderCount;
    }


    /**
     * 单量分析按天 oms
     */
    @Override
    public List<HomeOrderDto> getHomeOrderDto(Map<String, Object> map) {
        //判断 endTime 有没有超过当前日期 最大值去当前日期
        String endTime = map.get("endTime").toString();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate givenDate = LocalDate.parse(endTime, formatter);
        LocalDate currentDate = LocalDate.now();
        if (givenDate.isAfter(currentDate)) {
            endTime = currentDate.format(formatter);
        }
        map.put("diffDay", String.valueOf(DateUtils.getDiffDay(map.get("beginTime").toString(), endTime) + 1));
        return orderInputDao.getHomeOrderDto(map);
    }

    /**
     * 在库库存
     */
    @Override
    public StockInWhRes getStockInWh(String source, Long userId, Long companyId, Long whId, Long tenantId) {
        //在哭库存
        List<StockInWhDto> stockInWh = productStockDao.getStockInWh(source, userId, companyId, whId, tenantId);
        Map<Integer, List<StockInWhDto>> collect = stockInWh.stream().collect(Collectors.groupingBy(StockInWhDto::getType));
        //在途
        int transportSkuCount = productStockDao.getTransportSkuCount(source, userId, companyId, whId, tenantId);
        int transportBoxCount = productStockDao.getTransportBoxCount(source, userId, companyId, whId, tenantId);
        int inWhSkuCount = collect.get(1) == null ? 0 : collect.get(1).stream().mapToInt(StockInWhDto::getQuantity).sum();
        int inWhBoxCount = collect.get(2) == null ? 0 : collect.get(2).stream().mapToInt(StockInWhDto::getQuantity).sum();
        int canUseSkuKind = productStockDao.getCanUseSkuKind(source, userId, companyId, whId, tenantId);
        return new StockInWhRes(inWhSkuCount, inWhBoxCount, transportSkuCount, transportBoxCount, canUseSkuKind);
    }


    @Override
    public HomeCostRes getHomeCostDto(Map<String, Object> map) {
        List<HomeCostDto> honeList = costDao.getHomeCostDto(map);
        Map<Integer, HomeCostDto> collect = honeList.stream().collect(Collectors.toMap(HomeCostDto::getModuleType, i -> i));
        List<HomeCostDto> homeCostDtos = new ArrayList<>();
        double total = honeList.stream().mapToDouble(HomeCostDto::getCost).sum();
        for (StaticDict.Cost_ModuleType value : StaticDict.Cost_ModuleType.values()) {
            HomeCostDto homeCostDto = collect.get(value.getValue());
            if (homeCostDto == null) {
                homeCostDtos.add(new HomeCostDto(value.getValue(), value.getText(), 0d, "0%"));
            }
            else {
                homeCostDto.setModuleTypeName(value.getText());
                homeCostDto.setRate(total == 0 ? "0%" : MathUtils.numberFormat(homeCostDto.getCost() / total * 100, 2) +"%");
                homeCostDtos.add(homeCostDto);
            }
        }
        HomeCostRes res = new HomeCostRes();
        res.setTotal(total);
        res.setList(homeCostDtos);

        int diffDay = DateUtils.getDiffDay(map.get("beginTime").toString(), map.get("endTime").toString());
        String beginTime = map.get("beginTime").toString();
        //环比日期， 环比是两期连续数据做对比
        Date hEndTime = DateUtils.passingDate(DateUtils.stringFormatToDate(beginTime), -1);
        Date hBeginTime = DateUtils.passingDate(hEndTime, -diffDay);
        map.put("beginTime", DateUtils.dateFormatToString(hBeginTime));
        map.put("endTime", DateUtils.dateFormatToString(hEndTime));
        double huanSum = costDao.getHomeCostDto(map).stream().mapToDouble(HomeCostDto::getCost).sum();
        //同比日期，同比是不连续的两期数据做对比
        Calendar c = Calendar.getInstance();
        c.setTime(DateUtils.stringFormatToDate(beginTime));
        c.add(Calendar.YEAR, -1);
        Date tBeginTime = c.getTime();
        Date tEndTime = DateUtils.passingDate(tBeginTime, diffDay);
        map.put("beginTime", DateUtils.dateFormatToString(tBeginTime));
        map.put("endTime", DateUtils.dateFormatToString(tEndTime));
        double tongSum = costDao.getHomeCostDto(map).stream().mapToDouble(HomeCostDto::getCost).sum();


        if (total != 0) {
            res.setTongRate(MathUtils.numberFormat((total - tongSum) / total * 100, 2) + "%");
            res.setHuanRate(MathUtils.numberFormat((total - huanSum) / total * 100, 2) + "%");


        }
        res.setTongType(tongSum > total ? 1 : tongSum < total ? 2 : 0);
        res.setHuanType(huanSum > total ? 1 : huanSum < total ? 2 : 0);
        return res;
    }

}
